﻿using System;
using System.Collections.Generic;

namespace DimensionsHelper.Common.Contracts.Metadata;

/// <summary>
///     版本数据对象的操作类型：
///     <list type="number">
///         <item>None - 无操作</item>
///         <item>Add - 添加</item>
///         <item>Delete - 删除</item>
///     </list>
/// </summary>
public enum VersionOperations
{
    None,
    Add,
    Delete
}

/// <summary>
///     版本对象
/// </summary>
public interface IVersionObject : INamedObject
{
    /// <summary>
    ///     版本对象的操作类型，Add和Delete需要同时指定Index。
    /// </summary>
    VersionOperations Operation { get; }

    /// <summary>
    ///     操作集合对象时指定的索引，0开始。当此值小于0时，视作未指定。
    /// </summary>
    int Index { get; }

    /// <summary>
    ///     修改的对象。
    ///     <list type="number">
    ///         <item>如果指定了Index，向Target中添加或删除Data对象</item>
    ///         <item>如果未指定Index，使用Data的属性修改Target对象的属性值</item>
    ///     </list>
    /// </summary>
    object? Data { get; }

    /// <summary>
    ///     Data使用的对象名。
    /// </summary>
    string? ItemName { get; }

    /// <summary>
    ///     当前集合是否已经同步了。
    /// </summary>
    bool IsSynchronized { get; }

    /// <summary>
    ///     同步此版本对象集合。
    /// </summary>
    void Synchronize();
}


/// <summary>
///     版本对象集合。
/// </summary>
public interface IVersionObjectCollection : IEnumerable<IVersionObject>
{
    /// <summary>
    ///     当前集合中的元素数量。
    /// </summary>
    int Count { get; }

    /// <summary>
    ///     当前元数据对象所属的元数据文档。
    /// </summary>
    IMetadataDocument Document { get; }

    /// <summary>
    ///     获取指定索引的元素对象。
    /// </summary>
    /// <param name="index">指定索引，0开始</param>
    /// <returns>指定索引的元素对象</returns>
    IVersionObject this[int index] { get; }

    /// <summary>
    ///     当前集合的目标对象。
    /// </summary>
    object TargetObject { get; }

    /// <summary>
    ///     向集合中添加新的版本对象，并将IVersionObject.Data设置为UnsetValue。
    /// </summary>
    /// <param name="name">版本对象名称，可忽略，默认是空字符串。</param>
    /// <returns>新添加的版本对象</returns>
    IVersionObject AddNew(string name = "");

    /// <summary>
    ///     向集合中添加新的版本对象。
    /// </summary>
    /// <param name="data">版本对象修改的MDM对象</param>
    /// <param name="operation">集合操作</param>
    /// <param name="index">集合操作索引，如果<paramref name="operation" />是<see cref="VersionOperations.None" />，此值应是-1.</param>
    /// <param name="name">版本对象集合的名称，可忽略，默认是空字符串。</param>
    /// <returns>新添加的版本对象</returns>
    IVersionObject AddNew(object data, VersionOperations operation, int index, string name = "");
}


/// <summary>
///     MDM文档中的版本定义。
/// </summary>
public interface IVersion : IMetadataNamedObject
{
    /// <summary>
    ///     版本定义的全局唯一识别号。XML中Attribute名是id
    /// </summary>
    string Id { get; }

    /// <summary>
    ///     版本定义标签，默认是空字符串。XML中Attribute名是label
    /// </summary>
    string Label { get; }

    /// <summary>
    ///     版本定义描述，默认是空字符串。XML中Attribute名是description
    /// </summary>
    string Description { get; }

    /// <summary>
    ///     版本定义创建者名称。XML中Attribute名是createdby
    /// </summary>
    string CreateBy { get; }

    /// <summary>
    ///     主要名称
    /// </summary>
    string Major { get; }

    /// <summary>
    ///     次要名称
    /// </summary>
    string Minor { get; }

    /// <summary>
    ///     此版本使用的MDM文档版本号，默认是null。
    /// </summary>
    string? MdmVersion { get; }

    /// <summary>
    ///     子版本定义，默认是空列表。
    /// </summary>
    IVersionList SubVersions { get; }

    /// <summary>
    ///     是否是锁定的版本，默认是false。XML中Attribute名是locked
    /// </summary>
    bool IsLocked { get; }

    /// <summary>
    ///     此版本的创建时间。XML中Attribute名是datecreated
    /// </summary>
    DateTime DateCreated { get; }

    /// <summary>
    ///     此版本的锁定时间。XML中Attribute名是datelocked
    /// </summary>
    DateTime DateLocked { get; }

    /// <summary>
    ///     当前版本的所有版本对象集合。
    /// </summary>
    IReadOnlyList<IVersionObject> VersionObjectSet { get; }

    /// <summary>
    ///     此版本是否已经同步过。
    /// </summary>
    bool IsSynchronized { get; }

    /// <summary>
    ///     锁定当前版本，锁定后，此版本内对象将无法改变。
    /// </summary>
    void Lock();

    /// <summary>
    ///     向当前版本对象集合中追加新的对象。
    /// </summary>
    /// <param name="versionObject">添加的新版本对象</param>
    void Add(IVersionObject versionObject);

    /// <summary>
    ///     将此版本的修改内容同步到MDM文档。
    /// </summary>
    void Synchronize();
}


/// <summary>
///     MDM文档中的版本定义列表。XML文档中的Tag是versionlist。
/// </summary>
public interface IVersionList : IMetadataStringKeyCollection<IVersion>, IMetadataObject
{
    /// <summary>
    ///     最新的版本对象。
    /// </summary>
    IVersion? Latest { get; }
}